package pl.us.ij.plugins.segmentation.forms;

import com.jgoodies.forms.layout.CellConstraints;
import com.jgoodies.forms.layout.FormLayout;
import ij.ImagePlus;
import pl.us.ij.plugins.segmentation.SwitchImageListener;
import pl.us.ij.plugins.segmentation.commands.fire.FireSegmentationCommand;
import pl.us.ij.plugins.segmentation.commands.fire.FireSegmentationCommandParams;
import pl.us.ij.plugins.segmentation.infrastructure.CategoryInfo;
import pl.us.ij.plugins.segmentation.infrastructure.CommandParams;
import pl.us.ij.plugins.segmentation.localization.Localization;

import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import java.util.ResourceBundle;

/**
 * Created by IntelliJ IDEA.
 * User: Przemek
 * Date: 2010-05-26
 * Time: 00:40:32
 * To change this template use File | Settings | File Templates.
 */
public class PrairieFireForm extends CategoryInfo implements ChangeListener, SwitchImageListener {
    private JSlider bottomSlider;
    private JSlider topSlider;
    private JSlider degreeSlider;
    private JSlider removeSmallerSlider;
    private JButton segmentationButton;
    private JPanel firePanel;
    private JSpinner bottomSpinner;
    private JSpinner topSpinner;
    private JSpinner degreeSpinner;
    private JSpinner removeSmallerSpinner;
    private JLabel minLabel;
    private JLabel maxLabel;
    private boolean lockSliderSpinner;

    public PrairieFireForm(IActionHandler actionHandler) {
        actionHandler.setAction(segmentationButton, FireSegmentationCommand.class, getFireSegmentationParams());

        this.lockSliderSpinner = true;

        minLabel.setText("");
        maxLabel.setText("");

        bottomSlider.addChangeListener(this);
        bottomSpinner.addChangeListener(this);
        topSlider.addChangeListener(this);
        topSpinner.addChangeListener(this);
        degreeSlider.addChangeListener(this);
        degreeSpinner.addChangeListener(this);
        removeSmallerSlider.addChangeListener(this);
        removeSmallerSpinner.addChangeListener(this);

        bottomSpinner.setModel(new SpinnerNumberModel(bottomSlider.getValue(), bottomSlider.getMinimum(), bottomSlider.getMaximum(), 1));
        topSpinner.setModel(new SpinnerNumberModel(topSlider.getValue(), topSlider.getMinimum(), topSlider.getMaximum(), 1));
        degreeSpinner.setModel(new SpinnerNumberModel(degreeSlider.getValue(), degreeSlider.getMinimum(), degreeSlider.getMaximum(), 1));
        removeSmallerSpinner.setModel(new SpinnerNumberModel(removeSmallerSlider.getValue(), removeSmallerSlider.getMinimum(), removeSmallerSlider.getMaximum(), 1));

        this.lockSliderSpinner = false;
    }

    @Override
    public String getTitle() {
        return Localization.getString("prairieFireForm.title");
    }

    @Override
    public JPanel getPanel() {
        return firePanel;  //To change body of implemented methods use File | Settings | File Templates.
    }

    @Override
    public String getDescription() {
        return null;  //To change body of implemented methods use File | Settings | File Templates.
    }

    private ICommandParamGather getFireSegmentationParams() {
        return new ICommandParamGather() {
            public CommandParams getCommandParams() {
                FireSegmentationCommandParams params = new FireSegmentationCommandParams();

                params.setBottomThreshold(bottomSlider.getValue());
                params.setTopThreshold(topSlider.getValue());
                params.setSimilarity(degreeSlider.getValue());
                params.setObjectCount(removeSmallerSlider.getValue());

                return params;
            }
        };
    }

    @Override
    public void stateChanged(ChangeEvent e) {

        if (this.lockSliderSpinner) {
            return;
        }

        if (e.getSource() == bottomSlider) {
            bottomSpinner.setValue(bottomSlider.getValue());

            if (topSlider.getValue() < bottomSlider.getValue())
                topSlider.setValue(bottomSlider.getValue());

        } else if (e.getSource() == topSlider) {
            topSpinner.setValue(topSlider.getValue());

            if (bottomSlider.getValue() > topSlider.getValue())
                bottomSlider.setValue(topSlider.getValue());

        } else if (e.getSource() == degreeSlider) {
            degreeSpinner.setValue(degreeSlider.getValue());

        } else if (e.getSource() == removeSmallerSlider) {
            removeSmallerSpinner.setValue(removeSmallerSlider.getValue());

        } else if (e.getSource() == bottomSpinner) {
            bottomSlider.setValue((Integer) bottomSpinner.getValue());

            if (topSlider.getValue() < bottomSlider.getValue())
                topSlider.setValue(bottomSlider.getValue());

        } else if (e.getSource() == topSpinner) {
            topSlider.setValue((Integer) topSpinner.getValue());

            if (bottomSlider.getValue() > topSlider.getValue())
                bottomSlider.setValue(topSlider.getValue());

        } else if (e.getSource() == degreeSpinner) {
            degreeSlider.setValue((Integer) degreeSpinner.getValue());

        } else if (e.getSource() == removeSmallerSpinner) {
            removeSmallerSlider.setValue((Integer) removeSmallerSpinner.getValue());

        }
    }

    @Override
    public void imageActivated(ImagePlus imp) {
        this.lockSliderSpinner = true;

        try {
            ImagePlusInfo impInfo = new ImagePlusInfo(imp);

            int mx = (int) impInfo.getMax();
            int mn = (int) impInfo.getMin();

            Number valueBottom = (int) impInfo.fitRange((float) bottomSlider.getValue());
            Number valueTop = (int) impInfo.fitRange((float) topSlider.getValue());

            minLabel.setText("Min: " + mn);
            maxLabel.setText("Max: " + mx);

            topSlider.setMinimum(mn);
            topSlider.setMaximum(mx);
            topSlider.setValue(valueTop.intValue());

            bottomSlider.setMinimum(mn);
            bottomSlider.setMaximum(mx);
            bottomSlider.setValue(valueBottom.intValue());

            bottomSpinner.setModel(new SpinnerNumberModel(valueBottom, mn, mx, 1));
            topSpinner.setModel(new SpinnerNumberModel(valueTop, mn, mx, 1));
        }
        finally {
            this.lockSliderSpinner = false;
        }
    }

    @Override
    public void imageDeactivated(ImagePlus deactivatedImp, ImagePlus imp) {

        if (imp != null) {
            imageActivated(imp);
        }
    }

    {
// GUI initializer generated by IntelliJ IDEA GUI Designer
// >>> IMPORTANT!! <<<
// DO NOT EDIT OR ADD ANY CODE HERE!
        $$$setupUI$$$();
    }

    /**
     * Method generated by IntelliJ IDEA GUI Designer
     * >>> IMPORTANT!! <<<
     * DO NOT edit this method OR call it in your code!
     *
     * @noinspection ALL
     */
    private void $$$setupUI$$$() {
        final JPanel panel1 = new JPanel();
        panel1.setLayout(new FormLayout("fill:d:grow", "center:d:noGrow"));
        firePanel = new JPanel();
        firePanel.setLayout(new FormLayout("fill:107px:grow", "center:d:noGrow,top:4dlu:noGrow,center:max(d;4px):noGrow,top:4dlu:noGrow,center:max(d;4px):noGrow"));
        CellConstraints cc = new CellConstraints();
        panel1.add(firePanel, cc.xy(1, 1, CellConstraints.DEFAULT, CellConstraints.FILL));
        final JPanel panel2 = new JPanel();
        panel2.setLayout(new FormLayout("fill:d:grow,left:4dlu:noGrow,fill:70px:noGrow", "center:max(d;4px):noGrow,top:4dlu:noGrow,center:max(d;4px):noGrow,top:4dlu:noGrow,center:max(d;4px):noGrow,top:4dlu:noGrow,center:max(d;4px):noGrow,top:4dlu:noGrow,center:d:grow"));
        firePanel.add(panel2, cc.xy(1, 1, CellConstraints.FILL, CellConstraints.DEFAULT));
        panel2.setBorder(BorderFactory.createTitledBorder(ResourceBundle.getBundle("pl/us/ij/plugins/segmentation/localization/Localization").getString("prairieFireForm.objectsInRangeLabel")));
        final JLabel label1 = new JLabel();
        this.$$$loadLabelText$$$(label1, ResourceBundle.getBundle("pl/us/ij/plugins/segmentation/localization/Localization").getString("prairieFireForm.bottomThresholdLabel"));
        panel2.add(label1, cc.xy(1, 1));
        bottomSlider = new JSlider();
        bottomSlider.setMaximum(255);
        bottomSlider.setSnapToTicks(true);
        panel2.add(bottomSlider, cc.xy(1, 3, CellConstraints.FILL, CellConstraints.DEFAULT));
        final JLabel label2 = new JLabel();
        this.$$$loadLabelText$$$(label2, ResourceBundle.getBundle("pl/us/ij/plugins/segmentation/localization/Localization").getString("prairieFireForm.topThresholdLabel"));
        panel2.add(label2, cc.xy(1, 5));
        topSlider = new JSlider();
        topSlider.setMaximum(255);
        topSlider.setSnapToTicks(true);
        panel2.add(topSlider, cc.xy(1, 7, CellConstraints.FILL, CellConstraints.DEFAULT));
        bottomSpinner = new JSpinner();
        panel2.add(bottomSpinner, cc.xy(3, 3, CellConstraints.FILL, CellConstraints.DEFAULT));
        topSpinner = new JSpinner();
        panel2.add(topSpinner, cc.xy(3, 7, CellConstraints.FILL, CellConstraints.DEFAULT));
        minLabel = new JLabel();
        minLabel.setText("min: -999999");
        panel2.add(minLabel, cc.xy(3, 1));
        maxLabel = new JLabel();
        maxLabel.setText("max: 999999");
        panel2.add(maxLabel, cc.xy(3, 5));
        segmentationButton = new JButton();
        this.$$$loadButtonText$$$(segmentationButton, ResourceBundle.getBundle("pl/us/ij/plugins/segmentation/localization/Localization").getString("prairieFireForm.segmentizeLabel"));
        firePanel.add(segmentationButton, cc.xy(1, 5, CellConstraints.LEFT, CellConstraints.DEFAULT));
        final JPanel panel3 = new JPanel();
        panel3.setLayout(new FormLayout("fill:d:grow,left:4dlu:noGrow,fill:70px:noGrow", "center:max(d;4px):noGrow,top:4dlu:noGrow,center:max(d;4px):noGrow,top:4dlu:noGrow,center:max(d;4px):noGrow,top:4dlu:noGrow,center:max(d;4px):noGrow,top:4dlu:noGrow,center:d:grow"));
        firePanel.add(panel3, cc.xy(1, 3));
        panel3.setBorder(BorderFactory.createTitledBorder(ResourceBundle.getBundle("pl/us/ij/plugins/segmentation/localization/Localization").getString("prairieFireForm.objectsLabel")));
        final JLabel label3 = new JLabel();
        this.$$$loadLabelText$$$(label3, ResourceBundle.getBundle("pl/us/ij/plugins/segmentation/localization/Localization").getString("prairieFireForm.degreeOfSimilarityLabel"));
        panel3.add(label3, cc.xy(1, 1));
        degreeSlider = new JSlider();
        degreeSlider.setMaximum(255);
        degreeSlider.setSnapToTicks(true);
        panel3.add(degreeSlider, cc.xy(1, 3, CellConstraints.FILL, CellConstraints.DEFAULT));
        final JLabel label4 = new JLabel();
        this.$$$loadLabelText$$$(label4, ResourceBundle.getBundle("pl/us/ij/plugins/segmentation/localization/Localization").getString("prairieFireForm.removeSmallerThanLabel"));
        panel3.add(label4, cc.xy(1, 5));
        removeSmallerSlider = new JSlider();
        removeSmallerSlider.setMaximum(1000);
        removeSmallerSlider.setSnapToTicks(true);
        panel3.add(removeSmallerSlider, cc.xy(1, 7, CellConstraints.FILL, CellConstraints.DEFAULT));
        removeSmallerSpinner = new JSpinner();
        panel3.add(removeSmallerSpinner, cc.xy(3, 7, CellConstraints.FILL, CellConstraints.DEFAULT));
        degreeSpinner = new JSpinner();
        panel3.add(degreeSpinner, cc.xy(3, 3, CellConstraints.FILL, CellConstraints.DEFAULT));
    }

    /**
     * @noinspection ALL
     */
    private void $$$loadLabelText$$$(JLabel component, String text) {
        StringBuffer result = new StringBuffer();
        boolean haveMnemonic = false;
        char mnemonic = '\0';
        int mnemonicIndex = -1;
        for (int i = 0; i < text.length(); i++) {
            if (text.charAt(i) == '&') {
                i++;
                if (i == text.length()) break;
                if (!haveMnemonic && text.charAt(i) != '&') {
                    haveMnemonic = true;
                    mnemonic = text.charAt(i);
                    mnemonicIndex = result.length();
                }
            }
            result.append(text.charAt(i));
        }
        component.setText(result.toString());
        if (haveMnemonic) {
            component.setDisplayedMnemonic(mnemonic);
            component.setDisplayedMnemonicIndex(mnemonicIndex);
        }
    }

    /**
     * @noinspection ALL
     */
    private void $$$loadButtonText$$$(AbstractButton component, String text) {
        StringBuffer result = new StringBuffer();
        boolean haveMnemonic = false;
        char mnemonic = '\0';
        int mnemonicIndex = -1;
        for (int i = 0; i < text.length(); i++) {
            if (text.charAt(i) == '&') {
                i++;
                if (i == text.length()) break;
                if (!haveMnemonic && text.charAt(i) != '&') {
                    haveMnemonic = true;
                    mnemonic = text.charAt(i);
                    mnemonicIndex = result.length();
                }
            }
            result.append(text.charAt(i));
        }
        component.setText(result.toString());
        if (haveMnemonic) {
            component.setMnemonic(mnemonic);
            component.setDisplayedMnemonicIndex(mnemonicIndex);
        }
    }
}
